import 'dart:convert';
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:oktoast/oktoast.dart';
import 'package:yurun_smartmerchants/global.dart';
import 'package:yurun_smartmerchants/main.dart';
import 'package:yurun_smartmerchants/net/ApiInterface.dart';
import 'package:yurun_smartmerchants/routes/routes.dart';
import 'package:yurun_smartmerchants/utils/log_util.dart';

class NetUtil {
  static final debug = true;

  // static final host = 'https://whapitest.epfresh.cn';
  static final host = 'https://yrapitest.epfresh.cn';
  static final baseUrl = host + '/api/wmmsapp';

  //不需要consumerId参数的白名单数组
  static final whiteList = [
    ApiInterface.cmd_login,
    ApiInterface.cmd_verify_code,
    ApiInterface.cmd_update_app
  ];

  static final LogicError unknownError = LogicError(-1, "未知异常");

  // ignore: argument_type_not_assignable
  static final Dio _dio = new Dio(new BaseOptions(
      method: "post",
      baseUrl: baseUrl,
      connectTimeout: 10000,
      receiveTimeout: 10000,
      followRedirects: true));

  static Future<dynamic> postJson(String uri, Map<String, dynamic> body) =>
      _httpJson(uri, data: body).then(logicalErrorTransform).catchError((error) {
            if(error is DioError && error.error is SocketException){
              showToast("网络异常，请稍后重试");
            }
            if(error is LogicError){
              showToast(error.msg);
            }
      });

  static Future<dynamic> postentityJson(String uri,  dynamic body) =>
      _httpentityJson(uri, body).then(logicalErrorTransform).catchError((error) {
        if(error is DioError && error.error is SocketException){
          showToast("网络异常，请稍后重试");
        }
        if(error is LogicError){
          showToast(error.msg);
        }
      });

  static Future<Response<Map<String, dynamic>>> _httpJson(String uri,
      {Map<String, dynamic> data}) {
    //重新组织参数，添加公共参数
    Map requestParameter = new Map();
    requestParameter["parameters"] = data;
    requestParameter["cmd"] = uri;
    requestParameter["appDomain"] = "wisdomApp";
    requestParameter["clientIdentifierCode"] = "";
    //获取包信息
    requestParameter["appVersion"] = Global.packageInfo.version;
    //区分Android还是ios
    if (Platform.isIOS) {
      requestParameter["deviceInfo"] = {
        "os": "ios",
        "osVersion": "",
        "model": ""
      };
    } else if (Platform.isAndroid) {
      requestParameter["deviceInfo"] = {
        "os": "android",
        "osVersion": "",
        "model": ""
      };
    }
    String tempUrl = baseUrl;

    String token = Global.prefs.getString(Global.token);
    String consumerId = Global.prefs.getString(Global.consumer_id);
    if (token != null) {
      print('用户consumerId:$consumerId');
      tempUrl = tempUrl + '?token=' + token;
      if (!whiteList.contains(uri) &&
          consumerId != null &&
          consumerId.isNotEmpty) {
        requestParameter['consumerId'] = consumerId;
      }
    }

    /// 根据当前 请求的类型来设置 如果是请求体形式则使用json格式
    Options options = Options(contentType: 'application/json');
    if (debug) {
      print('请求url>>>$tempUrl>>>接口cmd===$uri');
      print('requestBody>>>' + json.encode(requestParameter) + '<<<<');
    }

    /// 统一带上token
    return _dio.post(tempUrl,
        data: json.encode(requestParameter), options: options);
  }

  static Future<Response<Map<String, dynamic>>> _httpentityJson(String uri,
      dynamic data) {
    //重新组织参数，添加公共参数
    Map requestParameter = new Map();
    requestParameter["parameters"] = data;
    requestParameter["cmd"] = uri;
    requestParameter["appDomain"] = "wisdomApp";
    requestParameter["clientIdentifierCode"] = "";
    //获取包信息
    requestParameter["appVersion"] = Global.packageInfo.version;
    //区分Android还是ios
    if (Platform.isIOS) {
      requestParameter["deviceInfo"] = {
        "os": "ios",
        "osVersion": "",
        "model": ""
      };
    } else if (Platform.isAndroid) {
      requestParameter["deviceInfo"] = {
        "os": "android",
        "osVersion": "",
        "model": ""
      };
    }
    String tempUrl = baseUrl;

    String token = Global.prefs.getString(Global.token);
    String consumerId = Global.prefs.getString(Global.consumer_id);
    if (token != null) {
      print('用户consumerId:$consumerId');
      tempUrl = tempUrl + '?token=' + token;
      if (!whiteList.contains(uri) &&
          consumerId != null &&
          consumerId.isNotEmpty) {
        requestParameter['consumerId'] = consumerId;
      }
    }

    /// 根据当前 请求的类型来设置 如果是请求体形式则使用json格式
    Options options = Options(contentType: 'application/json');
    if (debug) {
      print('请求url>>>$tempUrl>>>接口cmd===$uri');
      print('requestBody>>>' + json.encode(requestParameter) + '<<<<');
    }

    /// 统一带上token
    return _dio.post(tempUrl,
        data: json.encode(requestParameter), options: options);
  }


  /// 对请求返回的数据进行统一的处理
  /// 如果成功则将我们需要的数据返回出去，否则进异常处理方法，返回异常信息
  static Future<dynamic> logicalErrorTransform(
      Response<Map<String, dynamic>> resp) {
    if (debug) {
      print('响应状态码=${resp.data['statusCode']}');
//      print('responseBody--------$resp');
      LogUtil.d(resp);
      print('resp.data--------${resp.data}');
    }

    if (resp.data != null) {
      if (resp.data["statusCode"] == 200) {
        return Future.value(resp.data["response"]);
      }
    }

    LogicError error;
    if (resp.data != null && resp.data["error"] != null) {
      /// 失败时  错误提示在 data中时
      Map<String, dynamic> realData = resp.data["error"];
      error = new LogicError(realData["errorCode"], realData['errorInfo']);

      /// token失效 重新登录  后端定义的code码
      if (realData["errorCode"] == 401) {
        Future.delayed(Duration.zero, () {
          navigatorKey.currentState.pushNamedAndRemoveUntil(login_page, (route) => false);
        });
      }

    } else {
      error = unknownError;
    }
    return Future.error(error);
  }
}

///统一异常类
class LogicError {
  int errorCode;
  String msg;

  LogicError(errorCode, msg) {
    this.errorCode = errorCode;
    this.msg = msg;
  }
}
